package com.yhq.basic.thread.juc;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author hqyin
 * @date 2025/5/8 7:42 PM
 */
public class TestReentrantLock {
    public static void main(String[] args) {
//        test_producerAndConsumer();
        ReentrantLock lock1 = new ReentrantLock();
        lock1.tryLock();

    }

    private static void test_producerAndConsumer() {
        //使用condition实现生产者和消费者
        TestReentrantLock test = new TestReentrantLock();
        //
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    test.produce(i);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        },"Producer").start();


        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    test.consume();
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        },"Consumer").start();
    }

    private Object[] queue;
    /**
     * 生产下标
     */
    private int putIndex;
    /**
     * 消费下标
     */
    private int takeIndex;

    private ReentrantLock lock;

    private Condition notProduce;

    private Condition notConsume;

    private volatile  int size;

    public void produce(Object value) {
        lock.lock();
        try {
            //队列满了，则阻塞
            while (size == queue.length) {
                System.out.println("生产====>阻塞");
                notProduce.await();
            }

            //队列未满则消费
            System.out.println("生产："+ value);
            queue[putIndex] = value;
            if(queue.length ==++putIndex){
                putIndex=0;
            }
            if(++size==queue.length) {
                notConsume.signal();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void consume() {
        lock.lock();
        try {
            //队列满了，则阻塞
            while (size == 0) {
                System.out.println("消费====>阻塞");
                notConsume.await();
            }

            //队列未满则消费
            Object value = queue[takeIndex];
            queue[takeIndex]=null;
            System.out.println("消费："+ value);
            if(queue.length ==++takeIndex){
                takeIndex=0;
            }
            if(--size == 0){
                notProduce.signal();
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public TestReentrantLock() {
        queue = new Object[3];
        lock = new ReentrantLock();
        notProduce = lock.newCondition();
        notConsume = lock.newCondition();
    }
}
